package com.atom.common.delegate;

import java.util.Date;

import javax.annotation.Resource;

import org.activiti.engine.impl.util.json.JSONArray;
import org.activiti.engine.impl.util.json.JSONObject;
import org.apache.commons.codec.binary.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.atom.common.DelegateAction;
import com.atom.common.DelegateStatus;
import com.atom.common.DelegateType;
import com.atom.common.activiti.ActivitiHandler;
import com.atom.common.exception.AvensDelegateException;
import com.atom.common.remote.user.RemoteUserDao;
import com.atom.common.remote.user.UserUtil;
import com.atom.common.util.StringUtil;

/**
 * Title: DelegateService
 * Description: 处理平台推送的代理通知
 * @author WEWE
 * @date 2017年12月5日 上午11:41:38
 * @version 1.0
 */
@Service
@Transactional
public class DelegateService {

  @Resource RemoteUserDao remoteUserDao;
  @Resource ActivitiHandler activitiHandler;
  @Resource DelegateInfoDao delegateInfoDao;
  @Resource HistoricDelegateDao historicDelegateDao;

  public void delegate(String user, String agent, Date begintime, Date endtime, int type,
      String[] doctypeids, String action) {
    check(user, agent, begintime, endtime, type, doctypeids);
    if (StringUtils.equals(action, DelegateAction.ADD)) {
      add(user, agent, begintime, endtime, type, doctypeids);
    } else if (StringUtils.equals(action, DelegateAction.DEL)) {
      delete(user, agent, begintime, endtime, type, doctypeids);
    } else {
      throw new AvensDelegateException("action is invalid : " + action);
    }

  }

  private void add(String user, String agent, Date begintime, Date endtime, int type,
      String[] doctypeids) {
    UserUtil owner = getOwner(user);
  
    for (int i=0; i<doctypeids.length; i++) {
      DelegateInfo info = new DelegateInfo();
      info.setAssignee(agent);
      info.setOwner(user);
      info.setOwnerName(owner.getUsername());
      info.setOwnerOrg(owner.getOrgid());
      info.setOwnerOrgName(owner.getOrgname());
      info.setProcessDefinitionKey(doctypeids[i]);
      info.setStartTime(begintime);
      info.setEndTime(endtime);
      info.setDelegateType(type);
      info.setDelegateStatus(DelegateStatus.ADD_UNDO);
      info.setIsCancel(0);
      delegateInfoDao.save(info);
    }
  }

  private void delete(String user, String agent, Date begintime, Date endtime, int type,
      String[] doctypeids) {
    for (int i=0; i<doctypeids.length; i++) {
      DelegateInfo info = delegateInfoDao.findByAgentByUserByTypeByTime(agent, user, type, doctypeids[i], begintime);
      info.setEndTime(new Date());
      info.setIsCancel(1);
      delegateInfoDao.update(info);
    }
  
  }

  private void check(String user, String agent, Date begintime, Date endtime, int type,
      String[] doctypeids) {
    if (!StringUtil.hasText(user)) {
      throw new AvensDelegateException("user is invalid : " + user);
    }
    if (!StringUtil.hasText(agent)) {
      throw new AvensDelegateException("agent is invalid : " + agent);
    }
    if (begintime == null) {
      throw new AvensDelegateException("begintime is null");
    }
    if (endtime == null) {
      throw new AvensDelegateException("endtime is null");
    }
    if (DelegateType.COOP != type && DelegateType.OUT != type) {
      throw new AvensDelegateException("type is invalid : " + type);
    }
    for (int i=0; i<doctypeids.length; i++) {
      if (!activitiHandler.ProcDefKeyIsExist(doctypeids[i])) {
        throw new AvensDelegateException("doctypeid is invalid : " + doctypeids[i]);
      }
    }
  }

  private UserUtil getOwner(String user) {
    String userInfo = remoteUserDao.queryUserInfo("userid", user);
    JSONArray array = new JSONArray(userInfo);
    if (array == null || array.length() == 0) {
      throw new AvensDelegateException("user is not exist" + user);
    }
    JSONObject userJSON = array.getJSONObject(0);
    return new UserUtil(userJSON);
  }

}
